package com.tj.admin.rest.stats;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fqgj.common.api.annotations.ParamsValidate;
import com.fqgj.common.utils.DateUtil;
import com.fqgj.exception.common.ApiErrorException;
import com.fqgj.exception.common.ApplicationException;
import com.google.common.collect.Lists;
import com.tj.bo.common.conf.config.service.BizStatsSqlService;
import com.tj.bo.common.conf.api.ApiResponse;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Author: binary
 * Date: 2020/8/3 下午2:40
 */
@RestController
@RequestMapping("/bizStats")
public class StatsController {

    private static final Logger LOGGER = LoggerFactory.getLogger(StatsController.class);

    private final String KEY_LIST = "KeyList";

    @Autowired
    private BizStatsSqlService bizStatsSqlService;

    /**
     * 通用查询接口
     *
     * @param request
     * @return
     */
    @RequestMapping("/general/query")
    @ParamsValidate
    public ApiResponse generalQuery(@RequestBody JSONObject request) {
        String queryKey = request.getString("queryKey");
        List<String> list = Lists.newArrayList(queryKey);
        Map<String, Object> paramsMap = JSON.parseObject(JSON.toJSONString(request), Map.class);
        Object startDate = paramsMap.get("startDate");
        if (startDate != null) {
            paramsMap.put("startDate", startDate.toString().substring(0, 10));
        }

        Object endDate = paramsMap.get("endDate");
        if (endDate != null) {
            paramsMap.put("endDate", endDate.toString().substring(0, 10));
        }

        LOGGER.info("generalQuery,queryKey:{},params:{}", queryKey, paramsMap.toString());
        Map<String, Object> resultMap = this.getResult(list, paramsMap);
        return new ApiResponse(resultMap);
    }

    @RequestMapping("/general/export")
    public ApiResponse export(HttpServletRequest request, HttpServletResponse response, @RequestBody JSONObject jsonObject) {
        String queryKey = jsonObject.getString("queryKey");
        if (queryKey == null) {
            throw new ApplicationException("export error!");
        }
        ApiResponse apiResponse = this.generalQuery(jsonObject);
        if (apiResponse.getData() == null) {
            throw new ApplicationException("No Data!");
        }
        Map<String, Object> resultMap = (Map<String, Object>) apiResponse.getData();
        if (resultMap.size() > 0) {
            try {
                List<String> keyList = (List<String>) resultMap.get(queryKey + KEY_LIST);
                List<Map<String, Object>> dataList = (List) resultMap.get(queryKey);
                LOGGER.info("通用导出查询记录数,queryKey:{},记录数:{}", queryKey, dataList.size());
                Workbook workbook = new HSSFWorkbook();
                Sheet sheet = workbook.createSheet("Export Data List");
                Row firstRow = sheet.createRow(0);
                for (int i = 0; i < keyList.size(); i++) {
                    firstRow.createCell(i).setCellValue(String.valueOf(keyList.get(i)));
                }
                LOGGER.info("设置excel头成功,queryKey:{}", queryKey);
                for (int i = 0; i < dataList.size(); i++) {
                    Row row = sheet.createRow(i + 1);
                    Map<String, Object> objectMap = dataList.get(i);
                    if (i % 100 == 0) {
                        LOGGER.info("excel生成中,当前第{}条,queryKey:{}", i, queryKey);
                    }
                    for (int j = 0; j < keyList.size(); j++) {
                        Object value = objectMap.get(keyList.get(j));
                        if (value == null) {
                            value = "";
                        }
                        if (value instanceof Integer) {
                            row.createCell(j).setCellValue(String.valueOf(value));
                        } else if (value instanceof Double || value instanceof Float || value instanceof BigDecimal) {
                            row.createCell(j).setCellValue(new BigDecimal(String.valueOf(value)).setScale(2, BigDecimal.ROUND_HALF_UP).toString());
                        } else if (value instanceof String) {
                            row.createCell(j).setCellValue(String.valueOf(value));
                        } else if (value instanceof Date) {
                            row.createCell(j).setCellValue(DateUtil.getDate((Date) value));
                        } else {
                            row.createCell(j).setCellValue(String.valueOf(value));
                        }
                    }
                }
                OutputStream out = null;
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String currentDate = sdf.format(new Date());
                String excelName = "data";
                try {
                    out = response.getOutputStream();
                    response.setContentType("application/ms-excel;charset=UTF-8");
                    response.setHeader("Content-Disposition", "attachment;filename="
                            .concat(String.valueOf(URLEncoder.encode(currentDate + excelName + ".xls", "UTF-8"))));
                    workbook.write(out);
                } catch (IOException e) {
                    LOGGER.error("输出流错误{}", e);
                } finally {
                    out.close();
                }
            } catch (IOException e) {
                throw new ApiErrorException("导出失败");
            }
        }

        return new ApiResponse();
    }

    private Map<String, Object> getResult(List<String> list, Map<String, Object> paramsMap) {
        Map<String, Object> resultMap = new HashMap<>();
        for (String str : list) {
            Object result = null;
            try {
                result = bizStatsSqlService.getData(str, paramsMap);
                JSONObject jsonObject = new JSONObject();
                if (result instanceof List) {
                    putResultToRespJson(jsonObject, str, (List<Map<String, Object>>) result);
                } else {
                    jsonObject = JSON.parseObject(JSON.toJSONString(result));
                }
                resultMap.putAll(jsonObject);
            } catch (Exception e) {
                LOGGER.error("查询统计数据失败,key:{},result:{}", str, JSON.toJSONString(result), e);
            }
        }
        return resultMap;
    }

    /**
     * 下划线转驼峰
     *
     * @param str
     * @return
     */
    private String lineToHump(String str) {
        if (str == null) {
            return "";
        }
        if (!str.contains("_")) {
            return str.substring(0, 1).toLowerCase() + str.substring(1);
        }
        Pattern linePattern = Pattern.compile("_(\\w)");
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    private void putResultToRespJson(JSONObject jsonObject, String str, List<Map<String, Object>> result) {
        if (result != null && ((List) result).size() > 0) {
            //找到size最大的map作为标题
            Map<String, Object> columnMap = (Map<String, Object>) ((List) result).get(0);
            for (Object object : (List) result) {
                Map<String, Object> map = (Map<String, Object>) object;
                if (map.size() > columnMap.size()) {
                    columnMap = map;
                }
            }
            //组装key列表 按序号排 例：01~date、02~number
            List<String> keyList = new ArrayList<>();
            for (String key : columnMap.keySet()) {
                keyList.add(key);
            }
            Collections.sort(keyList, new Comparator<String>() {
                public int compare(String a, String b) {
                    return a.compareTo(b);
                }
            });
            for (int i = 0; i < keyList.size(); i++) {
                String[] tmp = keyList.get(i).split("~");
                keyList.set(i, tmp.length == 1 ? tmp[0] : tmp[1]);
            }
            jsonObject.put(lineToHump(str.replaceAll(" ", "_")) + KEY_LIST, keyList);
            //行实体的key 去除~
            List<Map<String, Object>> newResult = new ArrayList<>();
            for (Object object : (List) result) {
                Map<String, Object> map = (Map<String, Object>) object;
                Map<String, Object> temp = new HashMap<>();
                for (Map.Entry<String, Object> entry : map.entrySet()) {
                    String[] tmp = entry.getKey().split("~");
                    temp.put(tmp.length == 1 ? tmp[0] : tmp[1], entry.getValue());
                }
                newResult.add(temp);
            }
            jsonObject.put(lineToHump(str.replaceAll(" ", "_")), newResult);
        }
    }
}
